#if 0

#include <iostream>
#include <typeinfo>
#include <utility>
#include <vector>
#include <boost/type_index.hpp>
using namespace std;
using boost::typeindex::type_id;
using boost::typeindex::type_id_with_cvr;

int main()
{
    vector<int> v;
    auto it = v.cbegin();
    cout << "*** Using typeid\n";
    cout << typeid(const int).name() << endl;
    cout << typeid(v).name() << endl;
    cout << typeid(it).name() << endl;

    cout << "*** Using type_id\n";
    cout << type_id<const int>() << endl;
    cout << type_id<decltype(v)>() << endl;
    cout << type_id<decltype(it)>() << endl;

    cout << "*** Using type_id_with_cvr\n";
    cout << type_id_with_cvr<const int>() << endl;
    cout << type_id_with_cvr<decltype((v))>() << endl;       // 注意这里用了decltype(())
    cout << type_id_with_cvr<decltype(move((v)))>() << endl; // 注意这里用了decltype(())
    cout << type_id_with_cvr<decltype((it))>() << endl;      // 注意这里用了decltype(())
}

#elif 1

#include <iostream>
#include <typeinfo>
#include <boost/type_index.hpp>
using namespace std;
using boost::typeindex::type_id;

class shape
{
public:
    virtual ~shape() {}
};

class circle : public shape
{
};

#define CHECK_TYPEID(object, type)   \
    cout << "typeid(" #object << ")" \
         << (typeid(object) ==       \
                     typeid(type)    \
                 ? " is "            \
                 : " is NOT ")       \
         << #type << endl


#define CHECK_TYPE_ID(object,               \
                      type)                 \
    cout << "type_id(" #object              \
         << ")"                             \
         << (type_id<decltype(object)>() == \
                     type_id<type>()        \
                 ? " is "                   \
                 : " is NOT ")              \
         << #type << endl

         
int main()
{
    shape *ptr = new circle();
    CHECK_TYPEID(*ptr, shape);
    CHECK_TYPEID(*ptr, circle);
    CHECK_TYPE_ID(*ptr, shape);
    CHECK_TYPE_ID(*ptr, circle);
    delete ptr;
}
#endif